package com.zenithmind.document.pojo.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zenithmind.common.base.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

import jakarta.validation.constraints.*;

/**
 * 文档版本聚合根
 * 遵循单一职责原则：专注于版本信息管理
 * 遵循封装原则：通过方法控制版本状态
 * 遵循开闭原则：支持版本类型扩展
 *
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@EqualsAndHashCode(callSuper = true)
@Getter
@NoArgsConstructor
@TableName("document_version")
@Schema(description = "文档版本聚合根")
public class DocumentVersion extends BaseEntity {

    /**
     * 变更类型枚举
     */
    public enum ChangeType {
        CREATE(1, "新增"),
        MODIFY(2, "修改"),
        DELETE(3, "删除"),
        RESTORE(4, "恢复");

        private final int code;
        private final String description;

        ChangeType(int code, String description) {
            this.code = code;
            this.description = description;
        }

        public int getCode() { return code; }
        public String getDescription() { return description; }

        public static ChangeType fromCode(int code) {
            for (ChangeType type : values()) {
                if (type.code == code) {
                    return type;
                }
            }
            throw new IllegalArgumentException("未知的变更类型代码: " + code);
        }
    }

    /**
     * 文档ID
     */
    @NotBlank(message = "文档ID不能为空")
    @TableField("document_id")
    @Schema(description = "文档ID")
    private String documentId;

    /**
     * 版本号
     */
    @NotBlank(message = "版本号不能为空")
    @Size(max = 50, message = "版本号长度不能超过50个字符")
    @TableField("version_number")
    @Schema(description = "版本号")
    private String versionNumber;

    /**
     * 版本名称
     */
    @Size(max = 200, message = "版本名称长度不能超过200个字符")
    @TableField("version_name")
    @Schema(description = "版本名称")
    private String versionName;

    /**
     * 版本描述
     */
    @Size(max = 1000, message = "版本描述长度不能超过1000个字符")
    @TableField("description")
    @Schema(description = "版本描述")
    private String description;

    /**
     * 文件路径
     */
    @TableField("file_path")
    @Schema(description = "文件路径")
    private String filePath;

    /**
     * 文件URL
     */
    @TableField("file_url")
    @Schema(description = "文件URL")
    private String fileUrl;

    /**
     * 文件大小
     */
    @TableField("file_size")
    @Schema(description = "文件大小")
    private Long fileSize;

    /**
     * MD5哈希值
     */
    @TableField("md5_hash")
    @Schema(description = "MD5哈希值")
    private String md5Hash;

    /**
     * 是否为当前版本
     */
    @TableField("is_current")
    @Schema(description = "是否为当前版本")
    private Integer isCurrent;

    /**
     * 变更类型（1:新增, 2:修改, 3:删除, 4:恢复）
     */
    @TableField("change_type")
    @Schema(description = "变更类型")
    private Integer changeType;

    /**
     * 变更说明
     */
    @TableField("change_log")
    @Schema(description = "变更说明")
    private String changeLog;

    /**
     * 创建者ID
     */
    @NotBlank(message = "创建者ID不能为空")
    @TableField("creator_id")
    @Schema(description = "创建者ID")
    private String creatorId;

    // ========== 业务方法 ==========

    /**
     * 创建新版本
     */
    public static DocumentVersion create(String documentId, String versionNumber,
                                       String description, String creatorId) {
        DocumentVersion version = new DocumentVersion();
        version.setDocumentId(documentId);
        version.setVersionNumber(versionNumber);
        version.setDescription(description);
        version.setCreatorId(creatorId);
        version.setChangeType(ChangeType.CREATE.getCode());
        version.setIsCurrent(1);
        return version;
    }

    /**
     * 设置文档ID
     */
    public void setDocumentId(String documentId) {
        if (documentId == null || documentId.trim().isEmpty()) {
            throw new IllegalArgumentException("文档ID不能为空");
        }
        this.documentId = documentId;
    }

    /**
     * 设置版本号
     */
    public void setVersionNumber(String versionNumber) {
        if (versionNumber == null || versionNumber.trim().isEmpty()) {
            throw new IllegalArgumentException("版本号不能为空");
        }
        if (versionNumber.length() > 50) {
            throw new IllegalArgumentException("版本号长度不能超过50个字符");
        }
        this.versionNumber = versionNumber.trim();
    }

    /**
     * 设置版本名称
     */
    public void setVersionName(String versionName) {
        if (versionName != null && versionName.length() > 200) {
            throw new IllegalArgumentException("版本名称长度不能超过200个字符");
        }
        this.versionName = versionName;
    }

    /**
     * 设置版本描述
     */
    public void setDescription(String description) {
        if (description != null && description.length() > 1000) {
            throw new IllegalArgumentException("版本描述长度不能超过1000个字符");
        }
        this.description = description;
    }

    /**
     * 设置创建者ID
     */
    public void setCreatorId(String creatorId) {
        if (creatorId == null || creatorId.trim().isEmpty()) {
            throw new IllegalArgumentException("创建者ID不能为空");
        }
        this.creatorId = creatorId;
    }

    /**
     * 设置变更类型
     */
    public void setChangeType(Integer changeType) {
        if (changeType == null) {
            throw new IllegalArgumentException("变更类型不能为空");
        }
        // 验证变更类型是否有效
        ChangeType.fromCode(changeType);
        this.changeType = changeType;
    }

    /**
     * 设置是否为当前版本
     */
    public void setIsCurrent(Integer isCurrent) {
        this.isCurrent = isCurrent;
    }

    /**
     * 设置文件路径
     */
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    /**
     * 设置文件URL
     */
    public void setFileUrl(String fileUrl) {
        this.fileUrl = fileUrl;
    }

    /**
     * 设置文件大小
     */
    public void setFileSize(Long fileSize) {
        if (fileSize != null && fileSize < 0) {
            throw new IllegalArgumentException("文件大小不能为负数");
        }
        this.fileSize = fileSize;
    }

    /**
     * 设置MD5哈希值
     */
    public void setMd5Hash(String md5Hash) {
        this.md5Hash = md5Hash;
    }

    /**
     * 设置变更说明
     */
    public void setChangeLog(String changeLog) {
        this.changeLog = changeLog;
    }

    /**
     * 获取变更类型枚举
     */
    public ChangeType getChangeTypeEnum() {
        return changeType != null ? ChangeType.fromCode(changeType) : null;
    }

    /**
     * 检查是否为当前版本
     */
    public boolean isCurrent() {
        return Integer.valueOf(1).equals(isCurrent);
    }

    /**
     * 设置为当前版本
     */
    public void setAsCurrent() {
        this.isCurrent = 1;
    }

    /**
     * 设置为非当前版本
     */
    public void setAsNotCurrent() {
        this.isCurrent = 0;
    }

    /**
     * 比较版本号
     */
    public int compareVersion(DocumentVersion other) {
        if (other == null || other.getVersionNumber() == null) {
            return 1;
        }
        if (this.versionNumber == null) {
            return -1;
        }

        // 简单的版本号比较，假设格式为 x.y.z
        String[] thisParts = this.versionNumber.split("\\.");
        String[] otherParts = other.getVersionNumber().split("\\.");

        int maxLength = Math.max(thisParts.length, otherParts.length);

        for (int i = 0; i < maxLength; i++) {
            int thisPart = i < thisParts.length ? parseVersionPart(thisParts[i]) : 0;
            int otherPart = i < otherParts.length ? parseVersionPart(otherParts[i]) : 0;

            if (thisPart != otherPart) {
                return Integer.compare(thisPart, otherPart);
            }
        }

        return 0;
    }

    /**
     * 解析版本号部分
     */
    private int parseVersionPart(String part) {
        try {
            return Integer.parseInt(part);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    /**
     * 检查是否为更新版本
     */
    public boolean isNewerThan(DocumentVersion other) {
        return compareVersion(other) > 0;
    }

    /**
     * 检查是否为旧版本
     */
    public boolean isOlderThan(DocumentVersion other) {
        return compareVersion(other) < 0;
    }

    /**
     * 检查版本信息是否完整
     */
    public boolean isComplete() {
        return documentId != null && !documentId.trim().isEmpty() &&
               versionNumber != null && !versionNumber.trim().isEmpty() &&
               creatorId != null && !creatorId.trim().isEmpty() &&
               changeType != null;
    }

    /**
     * 格式化文件大小
     */
    public String getFormattedFileSize() {
        if (fileSize == null || fileSize <= 0) {
            return "0 B";
        }

        String[] units = {"B", "KB", "MB", "GB", "TB"};
        int unitIndex = 0;
        double size = fileSize.doubleValue();

        while (size >= 1024 && unitIndex < units.length - 1) {
            size /= 1024;
            unitIndex++;
        }

        return String.format("%.2f %s", size, units[unitIndex]);
    }

    /**
     * 生成版本标识
     */
    public String getVersionIdentifier() {
        return documentId + "_v" + versionNumber;
    }
}
